package com.dbh.company.commuting;
 
import com.uber.h3core.H3Core;
import com.uber.h3core.LengthUnit;
import com.uber.h3core.util.LatLng;
import org.apache.commons.lang.StringUtils;

import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
 
/**
 * UberH3Util
 *
 * @author zhangzhiheng
 * @date 2019/10/27
 */
public final class UberH3Util {
    private volatile static H3Core h3;
 
    private UberH3Util() {
    }
 
    public static H3Core getInstance() {
        if (h3 == null) {
            synchronized (UberH3Util.class) {
                if (h3 == null) {
                    try {
                        h3 = H3Core.newInstance();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
        return h3;
    }
 
    /**
     * 将经纬度编码为六边形地址
     *
     * @param lat
     * @param lng
     * @param res 分辨率 六边形平均长度：9.415526 米
     * @return
     */
    public static String latLngToH3Address(double lat, double lng, int res) {
        return getInstance().latLngToCellAddress(lat, lng, res);
    }
 
    public static String getParent(String hex, int res) {
        return getInstance().cellToParentAddress(hex, res);
    }
 
    public static double egeLengthM(int res) {
        return getInstance().edgeLength(res, LengthUnit.m);
    }
 
    /**
     * 获取边界
     *
     * @param hexAddr
     * @return
     */
    public static List<LatLng> h3ToLatLngBoundary(String hexAddr) {
        return getInstance().cellToBoundary(hexAddr);
 
    }
    /**
     * 获取中心点
     * @param hexAddr
     * @return
     */
    public static LatLng h3ToLatLngCenter(String hexAddr){
        return getInstance().cellToLatLng(hexAddr);
    }
 
//    public static String h3ToLatLngBoundaryStr(ArrayList<String> ids) {
//        getInstance().h3AddressSetToMultiPolygon(ids, false);
//    }
 
    public static String h3ToLatLngBoundaryStr(String hexAddr) {
        return StringUtils.join(h3ToLatLngBoundary(hexAddr).stream().map(p -> (p.lng + "," + p.lat)).collect(Collectors.toList()), "|");
    }
 
    /**
     * 获取相邻格子
     *
     * @param hex
     * @return
     */
    public static List<String> neighbour(String hex) {
        return getInstance().gridDisk(hex, 1);
    }
 
    /**
     * 合并格子
     *
     * @param hexSet
     * @return
     */
    public static List<String> compact(List<String> hexSet) {
        return getInstance().compactCellAddresses(hexSet);
    }
 
    /**
     * 求格子之间距离
     *
     * @param origin
     * @param des
     * @return
     */
    public static long h3Distance(String origin, String des) {
        return getInstance().gridDistance(origin, des);
    }

    public static void main(String[] args) {
        String hex = latLngToH3Address(41.420986666666664,113.53279, 10);
        System.out.println("hex-->" + hex);
        try {
            List<String> result = getInstance().gridDisk("8b31b5814ce8fff", 5);
            for(String str: result) {
                System.out.println(str);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        // List<String> result = Arrays.asList("8b31b5814ce8fff","8b31b5814ce9fff","8b31b5814cedfff","8b31b5814cecfff","8b31b5814cedfff","8b31b5814cecfff","8b31b5814c53fff","8b31b5814ce1fff","8b31b5814c53fff","8b31b5814c52fff","8b31b5814c53fff","8b31b5814ce1fff","8b31b5814c53fff","8b31b5814c52fff","8b31b5814c52fff","8b31b5814c50fff","8b31b5814c52fff","8b31b5814c52fff","8b31b5814c50fff","8b31b5814c50fff","8b31b5814c50fff","8b31b5814c50fff","8b31b5814c50fff","8b31b5814c50fff");
        List<String> hexList = Arrays.asList("8a31a6753a97fff","8a31a283261ffff","8a31a675ea1ffff","8a31a662496ffff","8a31a670b59ffff","8a31a674036ffff","8a31a29847a7fff","8a31a660324ffff","8a31a675eccffff","8a31a660c0affff","8a31a2984787fff","8a31a6746b2ffff","8a31a63956effff","8a31a664cc1ffff","8a31a6675c37fff","8a31a28326b7fff","8a31a666665ffff","8a31a67718a7fff","8a31a675c297fff","8a31a6663027fff","8a31a677244ffff","8a31a63ae9b7fff","8a31a675eaaffff","8a31a67584dffff","8a31a6cc805ffff","8a31a6198c9ffff","8a31a298080ffff","8a31a6313a1ffff","8a31a664cce7fff","8a31a6625b87fff","8a31a60d0cd7fff","8a31a6644b0ffff","8a31a6753207fff","8a31a043614ffff","8a31a675e477fff","8a31a610b787fff","8a31a29a066ffff","8a31a29b1b0ffff","8a31a29b1b07fff","8a31a675320ffff","8a31a62c8a67fff","8a31a62c8b5ffff","8a31a67718affff","8a31a67727a7fff","8a31a675890ffff","8a31a670b4a7fff","8a31a674e66ffff","8a31a628d6f7fff","8a31a60ae74ffff","8a31a662e757fff","8a31a28262dffff","8a31a677245ffff","8a31a676605ffff","8a31a639039ffff","8a31a670b487fff","8a31a6625a2ffff","8a31a675970ffff","8a31a6740c87fff","8a31a666d15ffff","8a31a63b386ffff","8a31a60ae747fff","8a31a661d59ffff","8a31a6645b6ffff","8a31a60ce02ffff","8a31a29847affff","8a31a6624857fff","8a31a670b857fff","8a31a662494ffff","8a31a63a16effff","8a31a670bbaffff","8a31a610b7b7fff","8a31a664ea77fff","8a31a6758827fff","8a31a60d0c8ffff","8a31a6741d9ffff","8a31a6746b0ffff","8a31a675b697fff","8a31a67421affff","8a31a6645627fff","8a31a6396d77fff","8a31a631359ffff","8a31a628804ffff","8a31a660326ffff","8a31a6565337fff","8a31a666b75ffff","8a31a6740c9ffff","8a31a6758957fff","8a31a63956cffff","8a31a661d4a7fff","8a31a6015857fff","8a31a664570ffff","8a31a662482ffff","8a31a0512387fff","8a31a677246ffff","8a31a6746b07fff","8a31a674e647fff","8a31a60d0cf7fff","8a31a62d28cffff","8a31a67180a7fff","8a31a6393407fff","8a31a29b1b1ffff","8a31a67533affff","8a31a60edae7fff","8a31a63984cffff","8a31a6289c0ffff","8a31a6753067fff","8a31a60c9b77fff","8a31a6772447fff","8a31a291010ffff","8a31a6a961a7fff","8a31a6750ac7fff","8a31a661d957fff","8a31a664545ffff","8a31a67ab08ffff","8a31a664a8d7fff","8a31a63919b7fff","8a31a6313ae7fff","8a31a6391d67fff","8a31a664cc0ffff","8a31a6a96187fff","8a31a2984797fff","8a31a6198c87fff","8a31a675306ffff","8a31a660eaa7fff","8a31a62d436ffff","8a31a675892ffff","8a31a6196187fff","8a31a639341ffff","8a31a661d4b7fff","8a31a675321ffff","8a31a6396d57fff","8a31a66603b7fff","8a31a660e3b7fff","8a31a675c2d7fff","8a31a675ea17fff","8a31a660c4affff","8a31a628806ffff","8a31a6751857fff","8a31a29114affff","8a31a661d487fff","8a31a6624967fff","8a31a664cdaffff","8a31a6625a0ffff","8a31a6624877fff","8a31a662492ffff","8a31a670b4cffff","8a31a675b69ffff","8a31a6753aeffff","8a31a67735b7fff","8a31a60a9907fff","8a31a670b877fff","8a31a6618aa7fff","8a31a675ece7fff","8a31a63b384ffff","8a31a6a961affff","8a31a29101affff","8a31a675c007fff","8a31a6772477fff","8a31a6313a0ffff");
        for(String str: hexList) {
            System.out.println(h3ToLatLngBoundaryStr(str));
        }
        System.out.println(h3Distance("8a31a62ab847fff","8a31a62a8a57fff"));
        System.out.println((int) ((50 * 1.41 - UberH3Util.egeLengthM(12) * 1.7 / 2) / (UberH3Util.egeLengthM(12) * 1.7) + 1));
//        System.out.println(neighbour("8c31aa520d2adff"));
        System.out.println(h3ToLatLngCenter("8c31aa520d2adff"));
    }
}